home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / EXAMPLES / EVALTEST.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  10.4 KB  |  508 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1996. */
  3.  
  4. /* This program is freely distributable without licensing fees 
  5.    and is provided without guarantee or warrantee expressed or 
  6.    implied. This program is -not- in the public domain. */
  7.  
  8. /* This program was originally written by someone else (Simon Hui?);
  9.    I just added a bit more GLUT stuff to it. */
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <stdlib.h>
  14. #include <math.h>
  15. #include <GL/glut.h>
  16.  
  17. #define VORDER 10
  18. #define CORDER 10
  19. #define TORDER 3
  20.  
  21. #define VMAJOR_ORDER 2
  22. #define VMINOR_ORDER 3
  23.  
  24. #define CMAJOR_ORDER 2
  25. #define CMINOR_ORDER 2
  26.  
  27. #define TMAJOR_ORDER 2
  28. #define TMINOR_ORDER 2
  29.  
  30. #define VDIM 4
  31. #define CDIM 4
  32. #define TDIM 2
  33.  
  34. #define ONE_D 1
  35. #define TWO_D 2
  36.  
  37. #define EVAL 3
  38. #define MESH 4
  39.  
  40. GLenum doubleBuffer;
  41.  
  42. float rotX = 0.0, rotY = 0.0, translateZ = -1.0;
  43.  
  44. GLenum arrayType = ONE_D;
  45. GLenum colorType = GL_FALSE;
  46. GLenum textureType = GL_FALSE;
  47. GLenum polygonFilled = GL_FALSE;
  48. GLenum lighting = GL_FALSE;
  49. GLenum mapPoint = GL_FALSE;
  50. GLenum mapType = EVAL;
  51.  
  52. double point1[10 * 4] =
  53. {
  54.   -0.5, 0.0, 0.0, 1.0,
  55.   -0.4, 0.5, 0.0, 1.0,
  56.   -0.3, -0.5, 0.0, 1.0,
  57.   -0.2, 0.5, 0.0, 1.0,
  58.   -0.1, -0.5, 0.0, 1.0,
  59.   0.0, 0.5, 0.0, 1.0,
  60.   0.1, -0.5, 0.0, 1.0,
  61.   0.2, 0.5, 0.0, 1.0,
  62.   0.3, -0.5, 0.0, 1.0,
  63.   0.4, 0.0, 0.0, 1.0,
  64. };
  65. double cpoint1[10 * 4] =
  66. {
  67.   0.0, 0.0, 1.0, 1.0,
  68.   0.3, 0.0, 0.7, 1.0,
  69.   0.6, 0.0, 0.3, 1.0,
  70.   1.0, 0.0, 0.0, 1.0,
  71.   1.0, 0.3, 0.0, 1.0,
  72.   1.0, 0.6, 0.0, 1.0,
  73.   1.0, 1.0, 0.0, 1.0,
  74.   1.0, 1.0, 0.5, 1.0,
  75.   1.0, 1.0, 1.0, 1.0,
  76. };
  77. double tpoint1[11 * 4] =
  78. {
  79.   0.0, 0.0, 0.0, 1.0,
  80.   0.0, 0.1, 0.0, 1.0,
  81.   0.0, 0.2, 0.0, 1.0,
  82.   0.0, 0.3, 0.0, 1.0,
  83.   0.0, 0.4, 0.0, 1.0,
  84.   0.0, 0.5, 0.0, 1.0,
  85.   0.0, 0.6, 0.0, 1.0,
  86.   0.0, 0.7, 0.0, 1.0,
  87.   0.0, 0.8, 0.0, 1.0,
  88.   0.0, 0.9, 0.0, 1.0,
  89. };
  90. double point2[2 * 3 * 4] =
  91. {
  92.   -0.5, -0.5, 0.5, 1.0,
  93.   0.0, 1.0, 0.5, 1.0,
  94.   0.5, -0.5, 0.5, 1.0,
  95.   -0.5, 0.5, -0.5, 1.0,
  96.   0.0, -1.0, -0.5, 1.0,
  97.   0.5, 0.5, -0.5, 1.0,
  98. };
  99. double cpoint2[2 * 2 * 4] =
  100. {
  101.   0.0, 0.0, 0.0, 1.0,
  102.   0.0, 0.0, 1.0, 1.0,
  103.   0.0, 1.0, 0.0, 1.0,
  104.   1.0, 1.0, 1.0, 1.0,
  105. };
  106. double tpoint2[2 * 2 * 2] =
  107. {
  108.   0.0, 0.0, 0.0, 1.0,
  109.   1.0, 0.0, 1.0, 1.0,
  110. };
  111. float textureImage[4 * 2 * 4] =
  112. {
  113.   1.0, 1.0, 1.0, 1.0,
  114.   1.0, 0.0, 0.0, 1.0,
  115.   1.0, 0.0, 0.0, 1.0,
  116.   1.0, 1.0, 1.0, 1.0,
  117.   1.0, 1.0, 1.0, 1.0,
  118.   1.0, 0.0, 0.0, 1.0,
  119.   1.0, 0.0, 0.0, 1.0,
  120.   1.0, 1.0, 1.0, 1.0,
  121. };
  122.  
  123. static void
  124. Init(void)
  125. {
  126.   static float ambient[] =
  127.   {0.1, 0.1, 0.1, 1.0};
  128.   static float diffuse[] =
  129.   {1.0, 1.0, 1.0, 1.0};
  130.   static float position[] =
  131.   {0.0, 0.0, -150.0, 0.0};
  132.   static float front_mat_diffuse[] =
  133.   {1.0, 0.2, 1.0, 1.0};
  134.   static float back_mat_diffuse[] =
  135.   {1.0, 1.0, 0.2, 1.0};
  136.   static float lmodel_ambient[] =
  137.   {1.0, 1.0, 1.0, 1.0};
  138.   static float lmodel_twoside[] =
  139.   {GL_TRUE};
  140.   static float decal[] =
  141.   {GL_DECAL};
  142.   static float repeat[] =
  143.   {GL_REPEAT};
  144.   static float nr[] =
  145.   {GL_NEAREST};
  146.  
  147.   glFrontFace(GL_CCW);
  148.  
  149.   glEnable(GL_DEPTH_TEST);
  150.  
  151.   glMap1d(GL_MAP1_VERTEX_4, 0.0, 1.0, VDIM, VORDER, point1);
  152.   glMap1d(GL_MAP1_COLOR_4, 0.0, 1.0, CDIM, CORDER, cpoint1);
  153.  
  154.   glMap2d(GL_MAP2_VERTEX_4, 0.0, 1.0, VMINOR_ORDER * VDIM, VMAJOR_ORDER, 0.0,
  155.     1.0, VDIM, VMINOR_ORDER, point2);
  156.   glMap2d(GL_MAP2_COLOR_4, 0.0, 1.0, CMINOR_ORDER * CDIM, CMAJOR_ORDER, 0.0,
  157.     1.0, CDIM, CMINOR_ORDER, cpoint2);
  158.   glMap2d(GL_MAP2_TEXTURE_COORD_2, 0.0, 1.0, TMINOR_ORDER * TDIM,
  159.     TMAJOR_ORDER, 0.0, 1.0, TDIM, TMINOR_ORDER, tpoint2);
  160.  
  161.   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  162.   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  163.   glLightfv(GL_LIGHT0, GL_POSITION, position);
  164.  
  165.   glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
  166.   glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
  167.  
  168.   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  169.   glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
  170.  
  171.   glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, decal);
  172.   glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat);
  173.   glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat);
  174.   glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, nr);
  175.   glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, nr);
  176.   glTexImage2D(GL_TEXTURE_2D, 0, 4, 2, 4, 0, GL_RGBA, GL_FLOAT,
  177.     (GLvoid *) textureImage);
  178. }
  179.  
  180. static void
  181. DrawPoints1(void)
  182. {
  183.   GLint i;
  184.  
  185.   glColor3f(0.0, 1.0, 0.0);
  186.   glPointSize(2);
  187.   glBegin(GL_POINTS);
  188.   for (i = 0; i < VORDER; i++) {
  189.     glVertex4dv(&point1[i * 4]);
  190.   }
  191.   glEnd();
  192. }
  193.  
  194. static void
  195. DrawPoints2(void)
  196. {
  197.   GLint i, j;
  198.  
  199.   glColor3f(1.0, 0.0, 1.0);
  200.   glPointSize(2);
  201.   glBegin(GL_POINTS);
  202.   for (i = 0; i < VMAJOR_ORDER; i++) {
  203.     for (j = 0; j < VMINOR_ORDER; j++) {
  204.       glVertex4dv(&point2[i * 4 * VMINOR_ORDER + j * 4]);
  205.     }
  206.   }
  207.   glEnd();
  208. }
  209.  
  210. static void
  211. DrawMapEval1(float du)
  212. {
  213.   float u;
  214.  
  215.   glColor3f(1.0, 0.0, 0.0);
  216.   glBegin(GL_LINE_STRIP);
  217.   for (u = 0.0; u < 1.0; u += du) {
  218.     glEvalCoord1d(u);
  219.   }
  220.   glEvalCoord1d(1.0);
  221.   glEnd();
  222. }
  223.  
  224. static void
  225. DrawMapEval2(float du, float dv)
  226. {
  227.   float u, v, tmp;
  228.  
  229.   glColor3f(1.0, 0.0, 0.0);
  230.   for (v = 0.0; v < 1.0; v += dv) {
  231.     glBegin(GL_QUAD_STRIP);
  232.     for (u = 0.0; u <= 1.0; u += du) {
  233.       glEvalCoord2d(u, v);
  234.       tmp = (v + dv < 1.0) ? (v + dv) : 1.0;
  235.       glEvalCoord2d(u, tmp);
  236.     }
  237.     glEvalCoord2d(1.0, v);
  238.     glEvalCoord2d(1.0, v + dv);
  239.     glEnd();
  240.   }
  241. }
  242.  
  243. static void
  244. RenderEval(void)
  245. {
  246.  
  247.   if (colorType) {
  248.     glEnable(GL_MAP1_COLOR_4);
  249.     glEnable(GL_MAP2_COLOR_4);
  250.   } else {
  251.     glDisable(GL_MAP1_COLOR_4);
  252.     glDisable(GL_MAP2_COLOR_4);
  253.   }
  254.  
  255.   if (textureType) {
  256.     glEnable(GL_TEXTURE_2D);
  257.     glEnable(GL_MAP2_TEXTURE_COORD_2);
  258.   } else {
  259.     glDisable(GL_TEXTURE_2D);
  260.     glDisable(GL_MAP2_TEXTURE_COORD_2);
  261.   }
  262.  
  263.   if (polygonFilled) {
  264.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  265.   } else {
  266.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  267.   }
  268.  
  269.   glShadeModel(GL_SMOOTH);
  270.  
  271.   switch (mapType) {
  272.   case EVAL:
  273.     switch (arrayType) {
  274.     case ONE_D:
  275.       glDisable(GL_MAP2_VERTEX_4);
  276.       glEnable(GL_MAP1_VERTEX_4);
  277.       DrawPoints1();
  278.       DrawMapEval1(0.1 / VORDER);
  279.       break;
  280.     case TWO_D:
  281.       glDisable(GL_MAP1_VERTEX_4);
  282.       glEnable(GL_MAP2_VERTEX_4);
  283.       DrawPoints2();
  284.       DrawMapEval2(0.1 / VMAJOR_ORDER, 0.1 / VMINOR_ORDER);
  285.       break;
  286.     }
  287.     break;
  288.   case MESH:
  289.     switch (arrayType) {
  290.     case ONE_D:
  291.       DrawPoints1();
  292.       glDisable(GL_MAP2_VERTEX_4);
  293.       glEnable(GL_MAP1_VERTEX_4);
  294.       glColor3f(0.0, 0.0, 1.0);
  295.       glMapGrid1d(40, 0.0, 1.0);
  296.       if (mapPoint) {
  297.         glPointSize(2);
  298.         glEvalMesh1(GL_POINT, 0, 40);
  299.       } else {
  300.         glEvalMesh1(GL_LINE, 0, 40);
  301.       }
  302.       break;
  303.     case TWO_D:
  304.       DrawPoints2();
  305.       glDisable(GL_MAP1_VERTEX_4);
  306.       glEnable(GL_MAP2_VERTEX_4);
  307.       glColor3f(0.0, 0.0, 1.0);
  308.       glMapGrid2d(20, 0.0, 1.0, 20, 0.0, 1.0);
  309.       if (mapPoint) {
  310.         glPointSize(2);
  311.         glEvalMesh2(GL_POINT, 0, 20, 0, 20);
  312.       } else if (polygonFilled) {
  313.         glEvalMesh2(GL_FILL, 0, 20, 0, 20);
  314.       } else {
  315.         glEvalMesh2(GL_LINE, 0, 20, 0, 20);
  316.       }
  317.       break;
  318.     default:;
  319.       /* Mesa makes GLenum be a C "enum" and gcc will warn if
  320.          all the cases of an enum are not tested in a switch
  321.      statement.  Add default case to supress the error. */
  322.     }
  323.     break;
  324.   }
  325. }
  326.  
  327. static void
  328. Reshape(int width, int height)
  329. {
  330.  
  331.   glViewport(0, 0, width, height);
  332.  
  333.   glMatrixMode(GL_PROJECTION);
  334.   glLoadIdentity();
  335.   glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 10.0);
  336.   glMatrixMode(GL_MODELVIEW);
  337. }
  338.  
  339. /* ARGSUSED1 */
  340. static void
  341. Key(unsigned char key, int x, int y)
  342. {
  343.   switch (key) {
  344.   case '1':
  345.     arrayType = ONE_D;
  346.     glDisable(GL_AUTO_NORMAL);
  347.     glutPostRedisplay();
  348.     break;
  349.   case '2':
  350.     arrayType = TWO_D;
  351.     glEnable(GL_AUTO_NORMAL);
  352.     glutPostRedisplay();
  353.     break;
  354.   case '3':
  355.     mapType = EVAL;
  356.     glutPostRedisplay();
  357.     break;
  358.   case '4':
  359.     mapType = MESH;
  360.     glutPostRedisplay();
  361.     break;
  362.   case '5':
  363.     polygonFilled = !polygonFilled;
  364.     glutPostRedisplay();
  365.     break;
  366.   case '6':
  367.     mapPoint = !mapPoint;
  368.     glutPostRedisplay();
  369.     break;
  370.   case '7':
  371.     colorType = !colorType;
  372.     glutPostRedisplay();
  373.     break;
  374.   case '8':
  375.     textureType = !textureType;
  376.     glutPostRedisplay();
  377.     break;
  378.   case '9':
  379.     lighting = !lighting;
  380.     if (lighting) {
  381.       glEnable(GL_LIGHTING);
  382.       glEnable(GL_LIGHT0);
  383.       if (arrayType == TWO_D) {
  384.         glEnable(GL_AUTO_NORMAL);
  385.       } else {
  386.         glDisable(GL_AUTO_NORMAL);
  387.       }
  388.     } else {
  389.       glDisable(GL_LIGHTING);
  390.       glDisable(GL_LIGHT0);
  391.       glDisable(GL_AUTO_NORMAL);
  392.     }
  393.     glutPostRedisplay();
  394.     break;
  395.   case 27:             /* Escape key. */
  396.     exit(0);
  397.   }
  398. }
  399.  
  400. static void
  401. Menu(int value)
  402. {
  403.   /* Menu items have key values assigned to them.  Just pass
  404.      this value to the key routine. */
  405.   Key((unsigned char) value, 0, 0);
  406. }
  407.  
  408. /* ARGSUSED1 */
  409. static void
  410. SpecialKey(int key, int x, int y)
  411. {
  412.  
  413.   switch (key) {
  414.   case GLUT_KEY_LEFT:
  415.     rotY -= 30;
  416.     glutPostRedisplay();
  417.     break;
  418.   case GLUT_KEY_RIGHT:
  419.     rotY += 30;
  420.     glutPostRedisplay();
  421.     break;
  422.   case GLUT_KEY_UP:
  423.     rotX -= 30;
  424.     glutPostRedisplay();
  425.     break;
  426.   case GLUT_KEY_DOWN:
  427.     rotX += 30;
  428.     glutPostRedisplay();
  429.     break;
  430.   }
  431. }
  432.  
  433. static void
  434. Draw(void)
  435. {
  436.  
  437.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  438.  
  439.   glPushMatrix();
  440.  
  441.   glTranslatef(0.0, 0.0, translateZ);
  442.   glRotatef(rotX, 1, 0, 0);
  443.   glRotatef(rotY, 0, 1, 0);
  444.   RenderEval();
  445.  
  446.   glPopMatrix();
  447.  
  448.   if (doubleBuffer) {
  449.     glutSwapBuffers();
  450.   } else {
  451.     glFlush();
  452.   }
  453. }
  454.  
  455. static void
  456. Args(int argc, char **argv)
  457. {
  458.   GLint i;
  459.  
  460.   doubleBuffer = GL_FALSE;
  461.  
  462.   for (i = 1; i < argc; i++) {
  463.     if (strcmp(argv[i], "-sb") == 0) {
  464.       doubleBuffer = GL_FALSE;
  465.     } else if (strcmp(argv[i], "-db") == 0) {
  466.       doubleBuffer = GL_TRUE;
  467.     }
  468.   }
  469. }
  470.  
  471. int
  472. main(int argc, char **argv)
  473. {
  474.   GLenum type;
  475.  
  476.   glutInit(&argc, argv);
  477.   Args(argc, argv);
  478.  
  479.   type = GLUT_RGB | GLUT_DEPTH;
  480.   type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
  481.   glutInitDisplayMode(type);
  482.   glutInitWindowSize(300, 300);
  483.   glutCreateWindow("Evaluator Test");
  484.  
  485.   glutCreateMenu(Menu);
  486.   glutAddMenuEntry("One dimensional", '1');
  487.   glutAddMenuEntry("Two dimensional", '2');
  488.   glutAddMenuEntry("Eval map type", '3');
  489.   glutAddMenuEntry("Mesh map type", '4');
  490.   glutAddMenuEntry("Toggle filled", '5');
  491.   glutAddMenuEntry("Toggle map point", '6');
  492.   glutAddMenuEntry("Toggle color", '7');
  493.   glutAddMenuEntry("Toggle texture", '8');
  494.   glutAddMenuEntry("Toggle lighting", '9');
  495.   glutAddMenuEntry("Quit", 27);
  496.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  497.   glutAttachMenu(GLUT_LEFT_BUTTON);
  498.  
  499.   Init();
  500.  
  501.   glutReshapeFunc(Reshape);
  502.   glutKeyboardFunc(Key);
  503.   glutSpecialFunc(SpecialKey);
  504.   glutDisplayFunc(Draw);
  505.   glutMainLoop();
  506.   return 0;
  507. }
  508.